/**
 * Created by XianTao on 2016/11/10
 * <p/>
 * Copyright (c) 2015-2015
 * Apache License
 * Version 2.0, January 2004
 * http://www.apache.org/licenses/
 */
package org.lego.wechat.portal.restful;

import lombok.extern.slf4j.Slf4j;
import org.lego.wechat.base.api.JsApiTicketApi;
import org.lego.wechat.base.encrypt.WxAesException;
import org.lego.wechat.base.encrypt.WxMsgCryptKit;
import org.lego.wechat.base.entity.WxCorp;
import org.lego.wechat.base.entity.WxJsTicket;
import org.lego.wechat.base.msg.in.InMsg;
import org.lego.wechat.base.msg.out.OutMsg;
import org.lego.wechat.portal.exception.NoReplyException;
import org.lego.wechat.portal.exception.RepeatMessageException;
import org.lego.wechat.portal.service.WechatHandler;
import org.lego.wechat.portal.service.WechatPortalService;
import org.lego.wechat.portal.service.WechatReceiver;
import org.lego.wechat.portal.service.WechatSender;
import org.lego.wechat.portal.vo.WxJsConfigVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;

@RestController
@Slf4j
public class WechatPortalRestful {
    @Autowired
    private WechatPortalService wechatPortalService;
    @Autowired
    private WechatReceiver wechatReceiver;
    @Autowired
    private WechatSender wechatSender;
    @Autowired
    private JsApiTicketApi jsApiTicketApi;

    @RequestMapping(value = "/msg/{corpId}/{agentId}", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String checkUrlValid(@PathVariable String corpId, @PathVariable Integer agentId, HttpServletRequest request) {
        WxCorp wxCorp = wechatPortalService.getValidWxCorp(corpId, agentId, request);
        String msgSignature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        log.info("msgSignature: " + msgSignature);
        log.info("timestamp: " + timestamp);
        log.info("nonce: " + nonce);
        log.info("echostr: " + echostr);

        try {
            WxMsgCryptKit wxMsgCryptKit = WxMsgCryptKit.create(wxCorp.getToken(), wxCorp.getEncodingAesKey(), corpId);
            String result = wxMsgCryptKit.verifyUrlNormal(msgSignature, timestamp, nonce, echostr);
            log.info("verify result: " + result);
            return result;
        } catch (WxAesException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @RequestMapping(value = "/msg/{corpId}/{agentId}", method = RequestMethod.POST)
    public String processRequest(@PathVariable String corpId, @PathVariable Integer agentId, HttpServletRequest request) {
        WxCorp wxCorp = wechatPortalService.getValidWxCorp(corpId, agentId, request);
        InMsg inMsg;
        try {
            inMsg = wechatReceiver.getInMsg(wxCorp, request);
        } catch (RepeatMessageException e) {
            return "";
        }

        List<WechatHandler> allHandlers = WechatHandler.allHandlers;
        if (!ObjectUtils.isEmpty(allHandlers)) {
            Collections.sort(allHandlers);
            for (WechatHandler handler : allHandlers) {
                if (handler.isMatch(inMsg)) {
                    OutMsg outMsg;
                    try {
                        outMsg = handler.process(inMsg);
                    } catch (NoReplyException e) {
                        return "";
                    }
                    if (outMsg != null) {
                        return wechatSender.getOutMsg(wxCorp, request, outMsg);
                    }
                }
            }
        }

        return "";
    }

    @RequestMapping(value = "/wxJs/config")
    @ResponseBody
    public WxJsConfigVo config(@RequestBody WxJsConfigVo wxJsConfigVo) {
        WxJsTicket wxJsTicket = jsApiTicketApi.getWxJsTicket(wxJsConfigVo.getCorpId(), wxJsConfigVo.getAgentId());
        // 确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认)，
        // 包括'http(s)://'部分，以及'？'后面的GET参数部分,但不包括'#'hash后面的部分
        return WxJsConfigVo.sign(wxJsTicket.getTicket(), wxJsConfigVo);
    }
}
